package com.fenshengou.xsm;

import android.os.Handler;
import android.support.annotation.Nullable;

import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.Arguments;

import cc.bodyplus.sdk.ble.manger.BleConnectionInterface;
import cc.bodyplus.sdk.ble.manger.BleConnectionManger;
import cc.bodyplus.sdk.ble.utils.DeviceInfo;
import cc.bodyplus.sdk.ble.utils.MyBleDevice;
import cc.bodyplus.sdk.ble.wave.HorizontalEcgWaveSurfaceView;
import cc.bodyplus.sdk.ble.utils.BleCmdConfig;



import android.widget.Toast;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactMethod;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;

public class BodyPlusModule extends ReactContextBaseJavaModule implements BleConnectionInterface {

    private static ReactContext reactContext;


    public BodyPlusModule(ReactApplicationContext context) {
        super(context);
        this.reactContext = context;
        BleConnectionManger.getInstance().addConnectionListener(this, true); // 注册蓝牙监听
//        reactContext = context;
    }

    @Override
    public String getName() {
        return "BodyPlusModule";
    }

    //   一个可选的方法getContants返回了需要导出给 JavaScript 使用的常量。
    // 它并不一定需要实现，但在定义一些可以被 JavaScript 同步访问到的预定义的值时非常有用。
    @Override
    public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>();
        return constants;
    }

    /**
     * 搜索附近蓝牙设备（S02产品）
     * 请求搜索是一个耗时的操作（耗时大于3秒），不宜频繁的执行，最好是在其回调的结果中执行下一次搜索刷新搜索列表
     */
    @ReactMethod
    public void search() {
        BleConnectionManger.getInstance().searchDevice();
        // Toast.makeText(getReactApplicationContext(), "开始搜索", Toast.LENGTH_SHORT).show();
    }


    /**
     * 连接设备（连接搜索列表中已有的设备）
     */
    @ReactMethod
    public void connectDevice(String macAddress, String deviceSn, int rssi, String deviceName, Boolean isDfuStatus) {
        MyBleDevice device = new MyBleDevice();
        device.setMacAddress(macAddress);
        device.setDeviceSn(deviceSn);
        device.setRssi(rssi);
        device.setDeviceName(deviceName);
        device.setDfuStatus(isDfuStatus);

        BleConnectionManger.getInstance().connectDevice(device);
        // Toast.makeText(getReactApplicationContext(), "连接中！", Toast.LENGTH_SHORT).show();
    }


    /**
     * 使用已知SN号达到自动重连的效果
     */
    @ReactMethod
    public void connectDeviceBySn(String sn) {
        BleConnectionManger.getInstance().autoConnectBle(sn);
        // Toast.makeText(getReactApplicationContext(), "连接中！", Toast.LENGTH_SHORT).show();
    }

    /**
     * 解绑并断开现有连接
     */
    @ReactMethod
    public void disConnect() {
        BleConnectionManger.getInstance().disconnect();
        // Toast.makeText(getReactApplicationContext(), "断开连接中！", Toast.LENGTH_SHORT).show();
    }

    @ReactMethod
    protected void onDestroy() {
        BleConnectionManger.getInstance().removeConnectionListener(this); // 移除监听
    }

    @ReactMethod
    protected void onResume() {
        BleConnectionManger.getInstance().fetchCoreMode(); // 读取位置信息
        BleConnectionManger.getInstance().fetchPowerLevel(); // 读取电量信息
    }

    /**
     * 自定义设备名称
     */
    @ReactMethod
    public void reName(String name) {
        BleConnectionManger.getInstance().changeBleName(name);
        // Toast.makeText(getReactApplicationContext(), "修改设备名称为" + name, Toast.LENGTH_SHORT).show();
    }


    @Override
    @ReactMethod
    public void reReNameSucceed() {
        // Toast.makeText(getReactApplicationContext(), "修改设备名称的返回", Toast.LENGTH_SHORT).show();
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", "true");
        sendEvent(reactContext, "reNameSucceed", params);
    }

    @Override
    @ReactMethod
    public void reBleStateOn() {
        // Toast.makeText(getReactApplicationContext(), "蓝牙打开的监听", Toast.LENGTH_SHORT).show();
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", "true");
        sendEvent(reactContext, "bleStateOn", params);
    }

    @Override
    @ReactMethod
    public void reOfflineStatus(boolean isOfflineStatus) {
        // Toast.makeText(getReactApplicationContext(), "设备处于离线状态回调", Toast.LENGTH_SHORT).show();
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", isOfflineStatus + "");
        sendEvent(reactContext, "offlineStatus", params);
    }

    @Override
    @ReactMethod
    public void reRssi(int rssi, int status) {
        // Toast.makeText(getReactApplicationContext(), "信号更改的回调", Toast.LENGTH_SHORT).show();
        Map<String, Object> rssiInfo = new HashMap<>(1);
        rssiInfo.put("rssi", rssi);
        rssiInfo.put("status", status);
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", rssiInfo.toString());
        sendEvent(reactContext, "rssi", params);
    }

    /**
     * 开始心率数据采集
     */
    @ReactMethod
    public void startEcg() {
        System.out.println("开始心率采集");
        // Toast.makeText(getReactApplicationContext(), "开始心率采集", Toast.LENGTH_SHORT).show();
        BleConnectionManger.getInstance().switchEcgChannel(true);
    }

    /**
     * 关闭心率数据采集
     */
    @ReactMethod
    public void closedEcg() {
        System.out.println("关闭心率采集");
        // Toast.makeText(getReactApplicationContext(), "关闭心率采集", Toast.LENGTH_SHORT).show();
        BleConnectionManger.getInstance().switchEcgChannel(false);
    }

    // 回调Body数据 肌电 心率 呼吸
    @Override
    public void bleDataCallBack(int code, int dm) {
        // Toast.makeText(getReactApplicationContext(), "回调Body数据 肌电 心率 呼吸", Toast.LENGTH_SHORT).show();
        String xinlv = "";
        // 心率数据的回调
        if (code == BleCmdConfig.BLE_HEART_MESSAGE) {
            xinlv = "心率：" + dm;
        } else if (code == BleCmdConfig.BLE_HEART_ERROR_MESSAGE) {
            xinlv = "心率异常 ： " + dm;
        } else if (code == BleCmdConfig.BLE_BREATHING_ERROR_MESSAGE) {
            xinlv = "呼吸率异常 ： " + dm;
        }
        Map<String, Object> data = new HashMap<>(1);
        data.put("code", code);
        data.put("dm", dm);
        data.put("status", xinlv);
        JSONObject jsonObj = new JSONObject(data);//转化为json格式
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", jsonObj.toString());
        sendEvent(reactContext, "dataCallBack", params);
    }

    @Override
    public void bleHeartDataError() {
       Toast.makeText(getReactApplicationContext(), "心率检测脱落", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void blePowerLevel(byte data) {
        // Toast.makeText(getReactApplicationContext(), "电量读取的返回、电量改变的回调", Toast.LENGTH_SHORT).show();
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", data + "");
        sendEvent(reactContext, "powerLevel", params);
    }

    @Override
    public void bleReConnectDevice(DeviceInfo device) {
        // 重连成功的回调
        // Toast.makeText(getReactApplicationContext(), "我是连接上的回调", Toast.LENGTH_SHORT).show();
        System.out.println(device);
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", device.toString());
        sendEvent(reactContext, "connectDevice", params);
    }

    @Override
    public void bleDeviceDisconnect(int status) {
        // 连接断开的回调
        // Toast.makeText(getReactApplicationContext(), "连接断开的回调", Toast.LENGTH_SHORT).show();
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", status + "");
        sendEvent(reactContext, "deviceDisconnect", params);
    }

    /**
     * Core位置变化的回调（主动触发）
     * byte[] data  说明：
     * data[0] == 00  充电座
     * data[0] == 01  上衣
     * data[0] == 10  裤子
     * data[0] == 11  独立
     *
     * @param data the data
     */
    @Override
    public void bleCoreModule(byte data) {
        // Toast.makeText(getReactApplicationContext(), "Core位置变化的回调（主动触发）", Toast.LENGTH_SHORT).show();
        String parts = "";
        switch (data) {
            case 0x00: // 充电座
                parts = "位置：充电";
                break;
            case 0x01: // 上衣
                parts = "位置：服装";
                break;
            case 0x11: // 独立
                parts = "位置：独立";
                break;
        }
        Map<String, Object> core = new HashMap<>(1);
        core.put("data", data);
        core.put("parts", parts);
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", core.toString());
        sendEvent(reactContext, "coreModule", params);
    }

    // 查找设备的回调，返回查找到的设备列表
    @Override
    public void reDeviceList(@Nullable ArrayList<MyBleDevice> lists) {
        // Toast.makeText(getReactApplicationContext(), "查找到的设备列表", Toast.LENGTH_SHORT).show();
        List list = new ArrayList();
        for (int i = 0; i < lists.size(); i++) {

            Map<String, Object> device = new HashMap<>(1);

            device.put("deviceSn", lists.get(i).getDeviceSn());
            device.put("macAddress", lists.get(i).getMacAddress());
            device.put("rssi", lists.get(i).getRssi());
            device.put("deviceName", lists.get(i).getDeviceName());
            device.put("isDfuStatus", lists.get(i).getDfuStatus());

            list.add(device);
        }
        WritableMap params = Arguments.createMap();
        params.putString("eventProperty", new JSONArray(list).toString());
        sendEvent(reactContext, "deviceList", params);
    }
    
    // 开启离线功能
    @ReactMethod
    public void startOffline() {
        BleConnectionManger.getInstance().setOfflineDataStatusLinster(new BleConnectionManger.OfflineDataAskLinster() {
            @Override
            public void onStatusBack(boolean hasOfflneData) {
                if (hasOfflneData){
                    // Toast.makeText(getReactApplicationContext(),"开启离线 失败 ：删除 本地离线数据 ，请再次开启 ！",Toast.LENGTH_SHORT).show();
                    BleConnectionManger.getInstance().offlineDataRest();
                }else {
                    // Toast.makeText(getReactApplicationContext(),"开启离线 成功 ：本地没有离线数据 ，开始采集！ ！",Toast.LENGTH_SHORT).show();
                    BleConnectionManger.getInstance().switchOfflineMode(true);
                }
                BleConnectionManger.getInstance().setOfflineDataStatusLinster(null);
            }
        });
        BleConnectionManger.getInstance().offlineDataAsk();

    }

    // 关闭离线功能
    @ReactMethod
    public void finishOffline() {
        BleConnectionManger.getInstance().switchOfflineMode(false);
        // mHandler.postDelayed(new Runnable() {
        //     @Override
        //     public void run() {
        //         BleConnectionManger.getInstance().offlineDataAsk();
        //     }
        // },1000);

        BleConnectionManger.getInstance().setOfflineDataStatusLinster(new BleConnectionManger.OfflineDataAskLinster() {
            @Override
            public void onStatusBack(boolean hasOfflneData) {
                System.out.println(hasOfflneData+"     asassasasas");
                if (hasOfflneData){
                    // Toast.makeText(getReactApplicationContext(),"同步离线数据 ：有数据 ，开始同步 ！ ！",Toast.LENGTH_SHORT).show();
                    BleConnectionManger.getInstance().offlineDataUpload();
                }else {
                    // Toast.makeText(getReactApplicationContext(),"同步离线数据 ：无数据 ，再见！ ！",Toast.LENGTH_SHORT).show();
                }
                BleConnectionManger.getInstance().setOfflineDataStatusLinster(null);
            }
        });
    }

    private void sendEvent(ReactContext reactContext, String eventName, @Nullable WritableMap params) {
        reactContext.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit(eventName, params);
    }
}
